<?php
/**
 * +----------------------------------------------------------------------+
 * php23种设计模式实现-访问者模式
 * Author：微信公众号：yuantanphp
 * 获取更多资源，技术答疑，项目合作请关注微信公众号：yuantanphp
 * +----------------------------------------------------------------------+
 */
namespace Visitor;

/**
 * 抽象项目状态
 */
abstract class State{
    protected $state;
    public abstract function getProjectAResult(ProjectA $projectA);
    public abstract function getProjectBResult(ProjectB $projectB);
}

//抽象项目
abstract class Project
{
    //项目名称
    public $projectName;
    //接受项目状态
    public abstract function Accept(State $visitor);
}
/** 
 * 提前完成
 */
class FinishedAdvance extends State{
    public function __construct(){
        $this->state = "提前完成";
    }
    public function getProjectAResult(ProjectA $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，给项目组发奖金 50000 并安排一次国内旅游。<br/>";

    }
    public function getProjectBResult(ProjectB $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，给项目组发奖金 100000 并安排一次出国旅游。<br/>";
    }
}
/** 
 * 如期完成
 */
class Finished extends State{
    public function __construct(){
        $this->state = "如期完成";
    }
    public function getProjectAResult(ProjectA $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，给项目组发奖金 20000 并安排一次国内旅游。<br/>";

    }
    public function getProjectBResult(ProjectB $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，给项目组发奖金 5000 并安排一次出国旅游。<br/>";
    }
}
/**
 * 逾期完成
 */
class BeOverdue  extends State{
    public function __construct(){
        $this->state = "逾期完成";
    }
    public function getProjectAResult(ProjectA $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，无额外奖励。<br/>";

    }
    public function getProjectBResult(ProjectB $projectA){
        echo "{$projectA->projectName}: 奖励规则 {$this->state}，无额外奖励。<br/>";
    }
}
//摩托车引擎研发项目
class ProjectA extends Project
{
    function __construct()
    {
        $this->projectName="制动研发";
    }
 
    public  function Accept(State $visitor)
    {
        $visitor->getProjectAResult($this);
    }
}
//制动系统研发
class ProjectB extends Project{
    function __construct()
    {
        $this->projectName="引擎研发";
    }
    public  function Accept(State $visitor)
    {
        $visitor->getProjectBResult($this);
    }
}
//对象结构
class ObjectStruct
{
    private $elements=array();
    //增加
    public function Add(Project $element)
    {
        array_push($this->elements,$element);
    }
    //移除
    public function Remove(Project $element)
    {
        foreach($this->elements as $k=>$v)
        {
            if($v==$element)
            {
                unset($this->elements[$k]);
            }
        }
    }
 
    //查看显示
    public function Display(State $visitor)
    {
        foreach ($this->elements as $v)
        {
            $v->Accept($visitor);
        }
    }
}
$os = new ObjectStruct();
$os->Add(new ProjectA());
$os->Add(new ProjectB());
//成功时反应
$ss = new FinishedAdvance();
$os->Display($ss);
$ss = new Finished();
$os->Display($ss);
$ss = new BeOverdue();
$os->Display($ss);